package com.test.application.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.aspectj.lang.reflect.SourceLocation;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.Method;

/**
 * 描述: AOP切点实现（注解方式）
 * 作者: yanruizhi
 * 时间: 2024/5/24 16:03
 */
@Component
@Aspect
public class AopExecuteClass {

    //后置执行   方法执行后执行
    @After(value = "@annotation(com.test.application.aop.annotation.EnableAopAfter)")
    public void after(JoinPoint point) {
        System.out.println("后置通知切点方法执行了......");
        Object[] args = point.getArgs();
        String kind = point.getKind();
        System.out.println(kind);
        for (Object arg : args) {
            System.out.println(arg.toString());
        }
    }

    //前置执行 方法执行前执行
    @Before(value = "@annotation(com.test.application.aop.annotation.EnableAopBefore)")
    public void before(JoinPoint point) {
        System.out.println("前置通知");
    }

    //环绕通知
    @Around(value = "@annotation(com.test.application.aop.annotation.EnableAopAround)")
    public Object pointcut(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping != null) {
            String[] paths = requestMapping.value();
            // 处理路径信息...
        }
        System.out.println("环绕通知--》前置");
        Object proceed = point.proceed();
        System.out.println("环绕通知--》后置");

        return proceed;

    }
    //异常通知 方法抛出异常后执行
    @AfterThrowing(value = "@annotation(com.test.application.aop.annotation.EnableAopAfterThrowing)")
    public void pointcut2(JoinPoint point) {
        System.out.println("异常通知执行");
    }

    //方法返回后执行
    @AfterReturning(value = "@annotation(com.test.application.aop.annotation.EnableAopAfterReturning)")
    public void pointcut3(JoinPoint point) {
        System.out.println("方法返回后执行");
    }

}
